# output.filename

- **Type:**

```ts
type FilenameConfig = {
  html?: string;
  js?:
    | string
    | ((
        pathData: Rspack.PathData,
        assetInfo: Rspack.JsAssetInfo | undefined,
      ) => string);
  css?:
    | string
    | ((
        pathData: Rspack.PathData,
        assetInfo: Rspack.JsAssetInfo | undefined,
      ) => string);
  svg?: string;
  font?: string;
  image?: string;
  media?: string;
  assets?: string;
};
```

- **Default:**

```js
// Development mode
const devDefaultFilename = {
  html: '[name].html',
  js: '[name].js',
  css: '[name].css',
  svg: '[name].[contenthash:8].svg',
  font: '[name].[contenthash:8][ext]',
  image: '[name].[contenthash:8][ext]',
  media: '[name].[contenthash:8][ext]',
  assets: '[name].[contenthash:8][ext]',
};

// Production mode
const prodDefaultFilename = {
  html: '[name].html',
  js: output.target === 'node' ? '[name].js' : '[name].[contenthash:8].js',
  css: '[name].[contenthash:8].css',
  svg: '[name].[contenthash:8].svg',
  font: '[name].[contenthash:8][ext]',
  image: '[name].[contenthash:8][ext]',
  media: '[name].[contenthash:8][ext]',
  assets: '[name].[contenthash:8][ext]',
};
```

Sets the filename of dist files.

After the production build, Rsbuild will add a hash in the middle of the filename by default. If you don't need to add it, you can set [output.filenameHash](/config/output/filename-hash) to `false` to disable this behavior.

The following are the details of each filename:

- `html`: The name of the HTML file.
- `js`: The name of the JavaScript files.
- `css`: The name of the CSS files.
- `svg`: The name of the SVG images.
- `font`: The name of the font files.
- `image`: The name of non-SVG images.
- `media`: The name of media assets, such as video.
- `assets`: The name of other static assets. Such as the assets defined in [Extend Asset Types](/guide/basic/static-assets#extend-asset-types).

> See [Output Files](/guide/basic/output-files) for more information.

## Example

To set the name of the JavaScript file to `[name]_script.js`, use the following configuration:

```js
export default {
  output: {
    filename: {
      js:
        process.env.NODE_ENV === 'production'
          ? '[name]_script.[contenthash:8].js'
          : '[name]_script.js',
    },
  },
};
```

:::tip Filename hash
Usually, Rsbuild only set the filename hash in the production mode (i.e., when `process.env.NODE_ENV === 'production'`).

If you set the filename hash in the development mode, it may cause HMR to fail (especially for CSS files). This is because every time the file content changes, the hash value changes, preventing bundler from reading the latest file content.
:::

## Template Strings

In the value of `output.filename`, you can use template strings to dynamically generate file names.

Common template strings include:

- `[name]` - entry name, which is the key of [source.entry](/config/source/entry).
- `[contenthash]` - hash value generated based on file content.
- `[contenthash:<length>]` - hash value generated based on file content, with specified hash length.
- `[ext]` - file extension, including the dot.

> For more template strings, refer to [Rspack - Template String](https://rspack.dev/config/output#template-string).

:::tip

- `filename.html` can only use certain template strings like `[name]` and `[contenthash:<length>]`.
- `filename.js` and `filename.css` do not support `[ext]`.

:::

## Filename of Async Modules

When you import a module via dynamic import, the module will be bundled into a single file, and its default naming rules are as follows:

- In the development mode, the filename will be generated based on the module path, such as `dist/static/js/async/src_add_ts.js`.
- In the production mode, it will be a random numeric id, such as `dist/static/js/async/798.27e3083e.js`. This is to avoid leaking the source code path in the production mode, and the number of characters is also less.

```js title="src/index.ts"
const { add } = await import('./add.ts');
```

If you want to specify a fixed name for the async module, you can use the [magic comments](https://rspack.dev/api/modules#magic-comments) provided by Rspack to achieve this, using `webpackChunkName ` to specify the module name:

```js title="src/index.ts"
const { add } = await import(
  /* webpackChunkName: "my-chunk-name" */ './add.ts'
);
```

After specifying the module name as above, the generated file will be `dist/static/js/async/my-chunk-name.js`.

## Using Function

You can pass a function to `output.filename.js` or `output.filename.css`, allowing you to dynamically generate filenames based on file information:

```js
export default {
  output: {
    filename: {
      js: (pathData, assetInfo) => {
        console.log(pathData); // You can check the contents of pathData here

        if (pathData.chunk?.name === 'index') {
          const isProd = process.env.NODE_ENV === 'production';
          return isProd ? '[name].[contenthash:8].js' : '[name].js';
        }

        return '/some-path/[name].js';
      },
      css: (pathData, assetInfo) => {
        if (pathData.chunk?.name === 'index') {
          const isProd = process.env.NODE_ENV === 'production';
          return isProd ? '[name].[contenthash:8].css' : '[name].css';
        }

        return '/some-path/[name].css';
      },
    },
  },
};
```

:::tip
Except for `output.filename.js`, other types of files currently do not support using functions.
:::

## Query Hash

If you need to generate hash values on the URL query of assets, you can refer to:

```js
const isProd = process.env.NODE_ENV === 'production';

export default {
  output: {
    filename: {
      js: isProd ? '[name].js?v=[contenthash:8]' : `[name].js`,
      css: isProd ? '[name].css?v=[contenthash:8]' : `[name].css`,
    },
  },
};
```

In this case, the filenames of JS and CSS will not include the hash, while the URLs in the HTML will contain a hash query.

```html
<!doctype html>
<html>
  <head>
    <script defer src="/static/js/index.js?v=b8565050"></script>
    <link href="/static/css/index.css?v=02d157ca" rel="stylesheet" />
  </head>
</html>
```
